package org.example.dao;

import org.example.entity.Budget;
import org.example.entity.Record;
import org.example.util.DBUtil;
import org.example.util.DateUtil;

import java.sql.Connection;
import java.sql.PreparedStatement;
import java.sql.ResultSet;
import java.sql.SQLException;
import java.util.ArrayList;
import java.util.Date;
import java.util.List;


/**
 * DAO类-Budget，对 budget 表进行增改删查操作，每月预算数据表的操作
 * 关于 "budget" 表，原作者是 "config" 表，存储键值对（key: value <=> String: String），但是由于 "config" 表中只存储了默认预算，
 * 所以笔者改成了 "budget" （预算）表，并存储1~12月预算和默认预算，保留原始数据类型（key: value <=> String: String）
 */
public class BudgetDAO {
    public static final String budget = "budget";           // 默认值
    public static final String default_budget = "500";      // 默认值

    /**
     * 添加配置（每月预算）
     *
     * @param key   预算名称，1~12月份预算名称、默认预算名称
     * @param value 预算值，单位元
     */
    public static void add(String key, String value) {
        String sql = "insert into budget (`key`,`value`) values (?,?)";
        try (Connection c = DBUtil.getConnection();
             PreparedStatement ps = c.prepareStatement(sql)) {
            ps.setString(1, key);
            ps.setString(2, value);
            ps.execute();
        } catch (SQLException e) {
            e.printStackTrace();
        }
    }


    /**
     * 通过查找预算名称 key，更新每月预算
     *
     * @param key   预算名称
     * @param value 预算值
     */
    public static void update(String key, String value) {
        Budget budget = getBudgetByKey(key);
        budget.setValue(value);
        String sql = "update budget set key = ? , value = ? where id = ?";
        try (Connection c = DBUtil.getConnection();
             PreparedStatement ps = c.prepareStatement(sql)) {
            ps.setString(1, budget.getKey());
            ps.setString(2, budget.getValue());
            ps.setInt(3, budget.getId());
            ps.executeUpdate();
        } catch (SQLException e) {
            e.printStackTrace();
        }
    }


    /**
     * 初始化数据库的每月预算
     */
    public static void init() {
        // 每个月的预算
        for (int i = 1; i <= 12; i++) {
            if (getBudgetByKey(budget + i) == null) {
                add(budget + i, default_budget);
            }
        }

        // 当月预算
        if (getBudgetByKey(budget) == null) {
            add(budget, default_budget);
        }
    }


    /**
     * 通过查找 key ，返回 Budget 对象
     *
     * @param key 预算名
     * @return Budget 预算对象
     */
    public static Budget getBudgetByKey(String key) {
        Budget budget = null;
        String sql = "select * from budget where key = ?";
        try (Connection c = DBUtil.getConnection();
             PreparedStatement ps = c.prepareStatement(sql)) {
            ps.setString(1, key);
            ResultSet result = ps.executeQuery();
            if (result.next()) {
                budget = new Budget(result.getInt("id"),
                        result.getString("key"),
                        result.getString("value"));
            }
        } catch (SQLException e) {
            e.printStackTrace();
        }
        return budget;
    }


    /**
     * 通过查找 key，返回 value （预算值）
     *
     * @param key 预算名
     * @return String 预算值（之后会转换成 int）
     */
    public static String getValueByKey(String key) {
        return getBudgetByKey(key).getValue();
    }


    /**
     * 把当月预算的字符串，转化成数字
     *
     * @return int
     */
    public static int getIntBudget() {
        return Integer.parseInt(getValueByKey(budget));
    }


    /**
     * 返回1~12月的月度预算
     *
     * @return List\<Budget>
     */
    public static List<Budget> listAllBudget() {
        String sql = "select * from budget";
        List<Budget> budgets = new ArrayList<>();
        try (Connection c = DBUtil.getConnection();
             PreparedStatement ps = c.prepareStatement(sql)) {
            ResultSet rs = ps.executeQuery();
            while (rs.next()) {
                if (rs.getString("key").equals(BudgetDAO.budget)) {
                    continue;
                }

                Budget budget = new Budget(
                        rs.getInt("id"),
                        rs.getString("key"),
                        rs.getString("value"));
                budgets.add(budget);
            }

            // 计算今年每月消费
            List<Date> listMonth = DateUtil.listMonthBeginOfThisYear();
            for (int i = 0; i < 12; i++) {
                double recordTotalSpend = 0;
                List<Record> recordList = RecordDAO.listAnyMonthByStartDay(listMonth.get(i));
                for (Record record : recordList) {
                    recordTotalSpend += record.getSpend();
                }
                budgets.get(i).setRecordTotalSpend(recordTotalSpend);
            }
        } catch (SQLException e) {
            e.printStackTrace();
        }
        return budgets;
    }
}
